﻿using UnityEngine;
using System.Collections.Generic;

namespace EchoFramework
{
    /// <summary>
    /// 有限状态机系统
    /// </summary>
    public class StateMachine
    {
        /// <summary>
        /// 有限状态机字典
        /// key:状态枚举
        /// value:状态对象
        /// </summary>
        protected Dictionary<FSMState, State> fsmStateDict = new Dictionary<FSMState, State>();
        /// <summary>
        /// 当前状态
        /// </summary>
        protected State curState = null;
        /// <summary>
        /// 属于的对象
        /// </summary>
        protected GameObject owner;
        /// <summary>
        /// 所属对象的Transform
        /// </summary>
        protected Transform ownerTrans => owner?.transform;

        public StateMachine(GameObject owner)
        {
            this.owner = owner;
        }

        public virtual void OnUpdate()
        {
            curState?.OnUpdate();
        }

        public virtual void OnFixedUpdate()
        {
            curState?.OnFixedUpdate();
        }

        /// <summary>
        /// 添加状态
        /// </summary>
        /// <param name="eState">状态</param>
        public void AddState(State eState)
        {
            if (eState == null)
            {
                GameLogger.LogWarning(string.Format("{0} 添加的状态为Null!", owner), owner);
                return;
            }
            if (eState.FsmState == FSMState.Null)
            {
                GameLogger.LogWarning(string.Format("{0} 添加的状态枚举为Null", owner), owner);
                return;
            }
            if (fsmStateDict.ContainsKey(eState.FsmState))
            {
                GameLogger.LogWarning(string.Format("{0} 已存在状态枚举 {1}", owner, eState.FsmState), owner);
                return;
            }
            fsmStateDict.Add(eState.FsmState, eState);
        }

        /// <summary>
        /// 删除状态
        /// </summary>
        /// <param name="eState">状态</param>
        public void DeleteState(State eState)
        {
            if (eState == null)
            {
                GameLogger.LogWarning(string.Format("{0} 删除的状态为Null!", owner), owner);
                return;
            }
            DeleteState(eState.FsmState);
        }

        /// <summary>
        /// 删除状态
        /// </summary>
        /// <param name="fsmState">状态枚举</param>
        public void DeleteState(FSMState fsmState)
        {
            if (fsmState == FSMState.Null)
            {
                GameLogger.LogWarning(string.Format("{0} 删除的状态枚举为Null", owner), owner);
                return;
            }
            if (!fsmStateDict.ContainsKey(fsmState))
            {
                GameLogger.LogWarning(string.Format("{0} 不存在状态枚举 {1}", owner, fsmState), owner);
                return;
            }
            fsmStateDict.Remove(fsmState);
        }

        /// <summary>
        /// 转换到下一个状态
        /// </summary>
        /// <param name="fsmTransition">过渡条件</param>
        public void TransitionState(FSMTransition fsmTransition)
        {
            if (curState == null)
            {
                GameLogger.LogWarning(string.Format("{0} 当前状态为Null", owner), owner);
                return;
            }
            if (fsmTransition == FSMTransition.Null)
            {
                GameLogger.LogWarning(string.Format("{0} 调用转换时，过渡条件枚举为Null", owner), owner);
                return;
            }
            FSMState nextFsmState = curState.GetNextState(fsmTransition);
            if (nextFsmState == FSMState.Null)
            {
                GameLogger.LogWarning(string.Format("{0} 调用转换时，下一个状态枚举为Null", owner), owner);
                return;
            }
            if(!fsmStateDict.ContainsKey(nextFsmState))
            {
                GameLogger.LogWarning(string.Format("{0} 调用转换时，下一个状态枚举为 {1} 不存在", owner, nextFsmState), owner);
                return;
            }
            curState.OnExit();
            curState = fsmStateDict[nextFsmState];
            curState.OnEnter();
        }

        /// <summary>
        /// 设置FSM启动时第一个状态
        /// </summary>
        /// <param name="eState">默认状态</param>
        public void SetDefaultState(State eState)
        {
            if(eState == null || eState.FsmState == FSMState.Null || !fsmStateDict.ContainsKey(eState.FsmState))
            {
                GameLogger.LogError(string.Format("{0} 设置默认状态失败！", owner), owner);
                return;
            }
            curState = eState;
            curState.OnEnter();
        }
    }
}
